<template src="./template.html"></template>

<script>
import BlockCircleProgress from '@/js/components/block-circle-progress'
// import ChartCircle from '@/js/components/chart-circle'
// import ChartLine from '@/js/components/chart-line'
// import ChartRadar from '@/js/components/chart-radar'
import Report from '../report'
import { SALES_LANGUAGE } from '../consts'
import AudioRecorder from '@/js/utils/audio/recorder'
import AudioVolume from '@/js/components/audio-volume'
import VideoRecorder from '@/js/components/video-recorder'
import VideoPreviewModal from '@/js/components/video-preview-modal'
import { uploadFile } from '@/js/common/common-models'
import { commitExercise, getExerciseReportState } from '../../../models'
import { playMp3, stopMp3 } from '@/js/utils/audio/player'
import { REFRESH_PAGE_STATUS } from 'store/mutation-types'

export default {
  // components: { BlockCircleProgress, ChartCircle, ChartLine, ChartRadar },
  components: { BlockCircleProgress, Report, AudioVolume, VideoRecorder, VideoPreviewModal },
  props: {
    currentLessonInfos: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      SALES_LANGUAGE,
      pageStatus: 'exercise', // exercise: 练习, reporting: 等待报告生成, finished: 练习完成
      totalTime: -1, // 无限计时模式
      liveStatus: 'start', // start: 开始录制, live: 录制中, over: 录制结束
      exerciseList: [
        {
          exerciseNumber: 1,
        },
        {
          exerciseNumber: 2,
        },
        {
          exerciseNumber: 3,
        },
      ], // 练习列表
      reportInfo: {}, // 报告信息
      volume: 0, // 音量
      audioInfo: null, // 录音信息
      videoInfo: null, // 视频信息
      videoPreviewModalVisible: false, // 视频预览弹窗是否显示
      percentage: 0, // 进度条百分比
      percentageInterval: null, // 进度条步长
      percentageType: 'file', // 进度条步长 file: 文件, report: 报告，error: 错误
      commitStart: 'success',
      exerciseId: null,
      intervalReport: false, // 轮询报告定时器
      startLoading: false, // 开始录制按钮是否显示加载中
      imageResult: null, // 图片上传结果
      videoResult: null, // 视频上传结果
      audioResult: null, // 音频上传结果
    }
  },
  computed: {
    getResultTitle() {
      if (this.percentageType === 'file') {
        return '正在上传视频...'
      } else if (this.percentageType === 'report') {
        return '视频上传成功，AI分析中...'
      } else {
        return '好像没捕捉到您的面部或声音，请确保光线充足、环境安静，并重新录制。'
      }
    }
  },
  watch: {
    pageStatus: {
      handler() {
        console.log('pageStatus--1', this.pageStatus)
        if (this.pageStatus === 'exercise' && this.liveStatus !== 'start') {
          // 练习中
          this.$store.state.user.exercisePageStatus = 'exercise'
        } else {
          this.$store.state.user.exercisePageStatus = ''
        }
      },
      immediate: true
    },
    liveStatus: {
      handler() {
        if (this.pageStatus === 'exercise' && this.liveStatus !== 'start') {
          // 练习中
          // this.$store.commit(EXERCISE_PAGE_STATUS, 'exercise')
          this.$store.state.user.exercisePageStatus = 'exercise'
        } else {
          // this.$store.commit(EXERCISE_PAGE_STATUS, '')
          this.$store.state.user.exercisePageStatus = ''
        }
      },
      immediate: true
    },
    currentLessonInfos: {
      handler(newVal) {
        // 判断报告状态
        if (newVal?.studySituation) {
          newVal.studySituation.forEach(it => {
            if (it.exerciseType === 102 && it.isGenerateReports === 2) {
            // 报告已生成
              this.pageStatus = 'finished'
              this.exerciseId = it.exerciseId
            } else if (it.exerciseType === 102 && it.isGenerateReports === 1 && this.$route.params.pageStatus !== 'exercise') {
            // 报告生成中
              // 需判断当前页面是否直接为练习页面，如果是则不进行轮询
              this.pageStatus = 'reporting'
              this.exerciseId = it.exerciseId
              this.percentageType = 'report'
              this.intervalReport = true
              this.pollReport().then((reportData) => {
                if (reportData && Number(reportData) === 2) {
                  this.pageStatus = 'finished'
                  this.exerciseId = it.exerciseId
                  // 刷新页面状态
                  this.$store.state.user.refreshPageStatus = true
                } else if (reportData && Number(reportData) === 3) {
                  // 生成报告失败，重新录制
                  this.percentageType = 'error'
                }
                clearInterval(this.percentageInterval)
                this.percentageInterval = null
              })
            }
          })
        }
        if (this.$store.state.user.refreshPageStatus) {
          this.$store.commit(REFRESH_PAGE_STATUS, false)
        } else if (this.$route.params.pageStatus === 'exercise') {
          this.pageStatus = 'exercise'
        }
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    /**
   * 设置事件监听器
   */
    setupEventListeners() {
      // 设置录音回调
      AudioRecorder.onStart(() => {
        console.log('录音开始');
      });

      AudioRecorder.onStop(() => {
        console.log('录音结束');
        this.volume = 0
      });

      AudioRecorder.onError((error) => {
        console.error('录音错误:', error);
      });
      AudioRecorder.onVolumeChange((volume) => {
        this.volume = volume
      })
    },
    onRecordingCompleted(result) {
      this.videoInfo = {
        ...result,
        screenshotUrl: this.videoInfo && this.videoInfo.screenshotUrl
      }
      console.log('录制完成', this.videoInfo)
    },
    $initSalesLanguage(salesLanguageMap) {
      return this.SALES_LANGUAGE.map(it => ({
        ...it,
        content: salesLanguageMap[it.params]
      }))
    },
    async $startLive() {
      // 开始录制
      // 计时器开始
      this.startLoading = true
      // 判断是否有录音权限
      const hasAudioPermission = await AudioRecorder.checkPermission()
      if (!hasAudioPermission) {
        this.$message.error('请授权录音权限')
        return
      }

      // 判断是否有视频权限
      const hasVideoPermission = await this.$refs.videoRecorder.checkPermission()
      if (!hasVideoPermission) {
        this.$message.error('请授权视频权限')
        return
      }

      // 开始录制
      const successRecording = await AudioRecorder.startRecording();
      console.log('开始录音结果', successRecording)
      if (!successRecording) {
        this.$message.error('开始录音失败')
        return
      }

      playMp3('assets/audio/start-audio.mp3')

      setTimeout(async () => {
        const successVideoRecording = await this.$refs.videoRecorder.startRecording()
        console.log('开始视频录制结果', successVideoRecording)
        if (!successVideoRecording) {
          this.$message.error('开始视频录制失败')
          return
        }

        this.totalTime = -1
        this.$refs.circleProgress.start()
        this.liveStatus = 'live'
        this.startLoading = false
      }, 4500)

      // 等待视频流加载完成后再截图
      setTimeout(async () => {
        try {
          const screenshot = await this.$refs.videoRecorder.takeScreenshot()
          console.log('截图结果', screenshot)
          if (screenshot && screenshot.url) {
            this.videoInfo = {
              ...this.videoInfo,
              screenshotUrl: screenshot.url,
              screenshotBlob: screenshot.blob,
              screenshotFileName: screenshot.fileName
            }
            // 获取截图后直接上传
            this.$uploadImage()
            console.log('截图URL设置成功:', screenshot.url)
          } else {
            console.warn('截图失败或返回空结果')
          }
        } catch (error) {
          console.error('截图过程中出错:', error)
        }
      }, 5500) // 等待2秒确保视频流加载完成
    },
    async $stopLive() {
      if (this.$refs.circleProgress.getDuration() < 5000) {
        console.log('录制时间过短', this.$refs.circleProgress.getDuration())
        this.$message.warning('录制时间过短')
        return
      }

      // 播放停止音频
      playMp3('assets/audio/over-audio.mp3')

      console.log('停止录制')

      // 结束录制
      const successStop = await AudioRecorder.stopRecording()
      this.$refs.videoRecorder.stopRecording()
      console.log('结束录音结果', successStop)
      if (successStop) {
        // 转换为WAV文件
        const audioInfo = await AudioRecorder.getRecordingInfo()
        this.audioInfo = audioInfo
      }
      this.$refs.circleProgress.stop()
      this.totalTime = this.$refs.circleProgress.getDuration()
      this.liveStatus = 'over'
    },
    async $uploadImage() {
      // 上传图片
      try {
        // 生成时间戳（在代码块顶部统一生成）
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
        // 从URL获取图片并创建File对象
        const screenshotFileName = this.videoInfo?.screenshotFileName || `screenshot-${timestamp}.png`

        const response = await fetch(this.videoInfo.screenshotUrl)
        const blob = await response.blob()
        const screenshotFile = new File([blob], screenshotFileName)
        // 获取文件大小
        console.log('screenshotFile大小', screenshotFile.size)
        const imageResult = await uploadFile({
          file: screenshotFile,
        })
        imageResult.data[0].isPicture = 1
        this.imageResult = imageResult
        console.log('上传图片结果', this.imageResult)
        this.$checkUpload()
      } catch (error) {
        console.error('上传图片失败:', error)
      }
    },
    async $uploadVideo() {
      try {
        // 上传视频
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
        const videoFileName = `video-${timestamp}.mp4`
        const videoResponse = await fetch(this.videoInfo.url)
        const videoBlob = await videoResponse.blob()
        const videoFile = new File([videoBlob], videoFileName)
        // 获取文件大小
        console.log('videoFile大小', videoFile.size)
        const startPercentage = this.percentage
        const videoResult = await uploadFile({
          file: videoFile,
        }, (progressNumber) => {
          this.percentage = startPercentage + progressNumber
        })
        this.videoResult = videoResult
        console.log('上传视频结果', this.videoResult)
        // 提交报告
        this.$checkUpload()
      } catch (error) {
        console.error('上传视频失败:', error)
        this.$message.error('上传作品失败:' + error.message)
        this.commitStart = 'failed'
      }
    },
    async $uploadAudio() {
      try {
        // 上传音频
        // 获取文件大小
        console.log('audioFile大小', this.audioInfo.file.size)
        const audioResult = await uploadFile({
          file: this.audioInfo.file,
        })
        this.audioResult = audioResult
        console.log('上传音频结果', this.audioResult)
        this.$checkUpload()
      } catch (error) {
        console.error('上传音频失败:', error)
        this.$message.error('上传作品失败:' + error.message)
        // this.commitStart = 'failed'
      }
    },
    async $checkUpload() {
      console.log('checkUpload---1', this.imageResult, this.videoResult)
      console.log('checkUpload---2', this.commitStart)
      if (!this.imageResult || !this.videoResult) {
        return
      }
      if (this.commitStart === 'failed') {
        return
      }
      // 提交报告
      const parmas = {
        files: [this.imageResult.data[0], this.videoResult.data[0]],
        lessonId: this.currentLessonInfos.lessonId,
        courseId: this.currentLessonInfos.courseId,
        exerciseType: 102,
        useTime: this.totalTime / 1000,
        platformInfo: {
          platform: 'web',
          ua: navigator.userAgent,
        }
      }
      const { message: exerciseId } = await commitExercise(parmas)
      this.exerciseId = exerciseId
      console.log('提交报告结果', exerciseId)
      // 轮询获取报告进度
      this.percentage = 0
      this.percentageType = 'report'
      this.intervalReport = true
      const reportData = await this.pollReport()
      if (reportData && Number(reportData) === 2) {
        // 刷新页面状态
        this.percentage = 100
        this.$store.state.user.refreshPageStatus = true
      } else if (reportData && Number(reportData) === 3) {
        // 生成报告失败，重新录制
        this.percentageType = 'error'
      }
      clearInterval(this.percentageInterval)
      this.percentageInterval = null
    },
    async $commitWork() {
      console.log('提交作品')
      // 提交作品
      stopMp3()
      this.commitStart = 'success'
      this.pageStatus = 'reporting'
      this.percentage = 0
      this.percentageType = 'file'
      this.videoResult = null
      this.audioResult = null

      // this.$uploadAudio()
      this.$uploadVideo()
      if (!this.imageResult) {
        // 如果图片上传失败，则重新上传
        this.$uploadImage()
      }
    },
    async pollReport() {
      if (this.percentage === 0) {
        // 如果进度为0, 虚拟开启进度条
        this.percentageInterval = setInterval(() => {
          this.percentage += 1
          if (this.percentage >= 95) {
            this.percentage = 95
            clearInterval(this.percentageInterval)
          }
        }, 1000)
      }

      const { data: reportData } = await getExerciseReportState({ exerciseId: this.exerciseId })
      console.log('获取报告进度结果', reportData)
      if (Number(reportData) !== 1) {
        return reportData
      }
      // 添加延迟避免频繁请求
      await new Promise(resolve => setTimeout(resolve, 3000))
      if (this.intervalReport && this.pageStatus === 'reporting') {
        return this.pollReport()
      } else {
        return null
      }
    },
    $restartLive() {
      // 重新开始
      this.pageStatus = 'exercise'
      this.audioInfo = null
      this.videoInfo = null
      this.videoPreviewModalVisible = false
      this.liveStatus = 'start'
      this.totalTime = -1
      if (this.$refs.circleProgress) {
        this.$refs.circleProgress.reset()
      }
      stopMp3()
      this.$nextTick(() => {
        this.$refs.videoRecorder.openCamera()
      })
    },
    $handleCommand(it) {
      // 切换报告
      console.log(it)
    },
  },
  mounted() {
    console.log(this.$scopedSlots.default)
    this.setupEventListeners()
    this.$nextTick(() => {
      if (this.$refs.videoRecorder) {
        this.$refs.videoRecorder.openCamera()
      }
    })
  },
  beforeDestroy() {
    this.intervalReport = false
    AudioRecorder.destroy()
    if (this.percentageInterval) {
      clearInterval(this.percentageInterval)
      this.percentageInterval = null
    }
  }
}
</script>
